﻿namespace MicroCloud.Entity
{
    #region "<see cref="IHash"/> 扩展操作类"
    /// <summary>
    /// <see cref="IHash"/> 扩展操作类
    /// </summary>
    public static class IHashExtensions
    {
        #region "方法"
        #region "获取指定对象的Hash值"
        /// <summary>
        /// 获取指定对象的Hash值
        /// </summary>
        /// <param name="hash">Hash对象</param>
        /// <param name="exceptNames">忽略的属性名</param>
        /// <param name="handlerType">处理器类型</param>
        /// <returns>Hash值</returns>
        public static string GetHash(this IHash hash, string[] exceptNames = null, Type handlerType = null)
        {
            handlerType ??= hash?.GetType();
            StringBuilder sb = new();
            exceptNames ??= new string[] { "ServiceProvider", "Logger" };
            //PropertyInfo[] properties = handlerType?.GetProperties(BindingFlags.Public | BindingFlags.Instance)?.Where(m => m.CanWrite && !exceptNames.Contains(m.Name))?.ToArray();
            PropertyInfo[] properties = handlerType?.GetProperties(BindingFlags.Public | BindingFlags.Instance)?.Where(m => !exceptNames.Contains(m.Name))?.ToArray();
            foreach (PropertyInfo property in properties)
            {
                var entityValue = property.GetValue(hash);
                sb.Append(entityValue?.ToJsonString());
            }
            var hashString = sb.ToString().ToMD5();
            return hashString;
        }
        #endregion
        #region "检查指定对象的Hash值，决定是否需要进行数据库同步"
        /// <summary>
        /// 检查指定对象的Hash值，决定是否需要进行数据库同步
        /// </summary>
        /// <param name="hash">Hash对象</param>
        /// <param name="provider">服务提供者</param>
        /// <param name="logger">日志对象</param>
        /// <param name="exceptNames">忽略的属性名</param>
        /// <param name="handlerType">处理器类型，默认实体类型</param>
        /// <param name="display">显示名称</param>
        /// <param name="remark">备注</param>
        /// <returns>同步返回true，不同步返回false</returns>
        public static bool CheckSyncByHash(this IHash hash, IServiceProvider provider, ILogger logger
            , string[] exceptNames = null, Type handlerType = null, string display = null, string remark = null)
        {
            if (hash == null)
            {
                return false;
            }
            handlerType ??= hash?.GetType();
            string hashString = hash.GetHash(exceptNames, handlerType);
            string key = $"Hash.SyncToDatabase-{handlerType.GetFullNameWithModule()}";

            var store = provider.GetService<IKeyValueStore>();
            var dictionary = store.GetByKey(key);
            if (dictionary != null && dictionary.Value?.ToString() == hashString)
            {
                logger.LogDebug("数据 {handlerType} 的内容签名 {hashString} 与上次相同，跳过数据库同步。", handlerType, hashString);
                return false;
            }

            display ??= handlerType?.GetDescription();
            store.CreateOrUpdate(key, hashString, display, remark).GetAwaiter().GetResult();
            logger.LogDebug("数据 {handlerType} 的内容签名 {hashString} 与上次 {value} 不同，执行数据库同步。", handlerType, hashString, dictionary?.Value);
            return true;
        }
        #endregion

        #endregion

    }
    #endregion

}
